package com.liuyu.common.framework.rocketmq.strategy.context;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.liuyu.common.framework.rocketmq.strategy.service.facade.TransactionServiceStrategy;
import com.liuyu.common.framework.rocketmq.vo.MqMessage;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * rocket事务方法逻辑处理策略上下文
 * @author: liuyu
 * @date: 2022/4/10 12:53
 * @version: 1
 */
@Component
public class MessageQueueProcessContext implements InitializingBean {
    private Map<String, TransactionServiceStrategy> map = new ConcurrentHashMap<>();
    @Autowired
    private List<TransactionServiceStrategy> strategies;

    public static final int MAX_TRY_TIMES = 3;


    /**
     * Invoked by the containing {@code BeanFactory} after it has set all bean properties
     * and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
     * <p>This method allows the bean instance to perform validation of its overall
     * configuration and final initialization when all bean properties have been set.
     * @throws Exception in the event of misconfiguration (such as failure to set an
     * essential property) or if initialization fails for any other reason
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        for (TransactionServiceStrategy strategy : strategies) {
            map.put(strategy.getQueueType(), strategy);
        }
    }


    /**
     * 执行本地方法
     * @author liuyu
     * @date 2022/4/9 21:57
     * @param message
     * @param o
     * @return boolean
     */
    public boolean executeTransaction(Message message, Object o) {
        MqMessage message1 = JSON.parseObject(new String((byte[]) message.getPayload()), new TypeReference<MqMessage>() {
        });
        TransactionServiceStrategy strategy = map.get(message1.getMessageType());
        if (strategy == null) {
            return true;
        } else {
            return strategy.executeTransaction(message, o);
        }
    }


    public int getMaxTryTimes(Message message) {
        MqMessage message1 = JSON.parseObject(new String((byte[]) message.getPayload()), new TypeReference<MqMessage>() {
        });
        TransactionServiceStrategy strategy = map.get(message1.getMessageType());
        if (strategy == null) {
            return MAX_TRY_TIMES;
        } else {
            return strategy.getMaxTryTimes();
        }
    }
}
